//#include <wx/log.h>
#include "AMFObject.h"
#include "wxAMF.h"
#include <vector>
//#include <wx/log.h>


using namespace std;

AMFObject::AMFObject()
{
//    wxLogMessage(_("建立AMFObject"));
    _amf3 = false;
    _type = AMF0DataType::Null;
}

AMFObject::AMFObject(bool isAMF3)
{
//    wxLogMessage(_("建立AMFObject"));
    _amf3 = isAMF3;
    _type = AMF0DataType::Null;
}

AMFObject::AMFObject(bool isAMF3, wxString content)
{
    //ctor
//    wxLogMessage(_("建立AMFObject"));
    _amf3 = isAMF3;
    if (!content.IsEmpty()) {
        _type = isAMF3?0x06:0x02;
        _content = new wxString(content);
    }
}

AMFObject::AMFObject(bool isAMF3, wxByte type, void *content)
{
//    wxLogMessage(_("建立AMFObject"));
    _amf3 = isAMF3;
    _type = type;
    _content = content;
}

AMFObject::~AMFObject()
{
//    wxLogMessage(_("釋放AMFObject"));
        //dtor

    if(_amf3) {
        switch(_type) {
            case AMF3DataType::Double:
                delete (double*)_content;
                break;
            case AMF3DataType::Integer:
                delete (int*)_content;
                break;
            case AMF3DataType::String:
                ((wxString*)_content)->Clear();
                delete (wxString*)_content;
                break;
            case AMF3DataType::Array:
                for(unsigned int i = 0; i < ((vector<AMFObject*>*)_content)->size(); i++)
					delete (*(vector<AMFObject*>*)_content)[i];
                ((vector<AMFObject*>*)_content)->clear();
                delete (vector<AMFObject*>*)_content;
                break;
            case AMF3DataType::Object:
                Hashtable *ot = (Hashtable*)_content;
                for (Hashtable::iterator it = ot->begin(); it != ot->end(); ++it ) delete it->second;
                ot->clear();
                delete ot;
                break;
        }
    }
    else {
        switch(_type) {
            case AMF0DataType::Array:
                for(unsigned int i = 0; i < ((vector<AMFObject*>*)_content)->size(); i++) delete (*(vector<AMFObject*>*)_content)[i];
                ((vector<AMFObject*>*)_content)->clear();
                delete (vector<AMFObject*>*)_content;
                break;
            case AMF0DataType::AMF3Data:
                delete (AMFObject*)_content;
                break;
        }
    }
}

wxString AMFObject::toString(bool writeType)
{
        wxString tmp;
        vector<AMFObject*>::iterator iter;
        Hashtable::iterator it;
        vector<AMFObject*> *clist = NULL;
        Hashtable *table = NULL;
        int *i = NULL;
        double *d = NULL;
        bool isfirst = true;
        if (_amf3) {
            switch (_type) {
                case AMF3DataType::String:
                    if (writeType) tmp.append(_("'")).append(*((const wxString*)(_content))).append(_("'"));
                    else  tmp.append(*((const wxString*)(_content)));
                    break;
                case AMF3DataType::Array:
                    tmp = _("Array3 [\r\n");
                    clist = (vector<AMFObject*>*)_content;
                    for (iter = clist->begin(); iter != clist->end(); ++iter) {
                        AMFObject *current = *iter;
                        if (isfirst) isfirst = false;
                        else tmp += _(", ");
                        tmp += current->toString(writeType);
                        tmp += _("\r\n");
                    }
                    tmp += _("]");
                    break;
                case AMF3DataType::Object:
                    table = (Hashtable*)_content;
                    tmp = _("Hashtable {\r\n");
                    for ( it = table->begin(); it != table->end(); ++it ) {
                        if (isfirst) isfirst = false;
                        else tmp += _(", ");
                        tmp += it->first + _(":");
                        tmp += it->second->toString(writeType);
                        tmp += _("\r\n");
                    }
                    tmp += _("}");
                    break;
                case AMF3DataType::Null:
                    tmp = _("null");
                    if (writeType) tmp += _("(NULL)");
                    break;
                case AMF3DataType::True:
                    tmp = _("true");
                    if (writeType) tmp += _("(True)");
                    break;
                case AMF3DataType::False:
                    tmp = _("false");
                    if (writeType) tmp += _("(False)");
                    break;
                case AMF3DataType::Integer:
                    i = (int*)_content;
                    tmp += wxString::Format(_("%d"), *i);
                    if (writeType) tmp += _("(Integer)");
                    break;
                case AMF3DataType::Double:
                    d = (double*)_content;
                    tmp += wxString::Format(_("%d"),(int) *d);
                    if (writeType) tmp += _("(Double)");
                    break;
                default:
                    return _("Unknow Type");
            }
        }
        else {
            switch (_type) {
                case AMF0DataType::Array:
                    tmp = _("Array0 [\r\n");
                    clist = (vector<AMFObject*>*)_content;
                    for (iter = clist->begin(); iter != clist->end(); ++iter) {
                        AMFObject *current = *iter;
                        if (isfirst) isfirst = false;
                        else tmp += _(", ");
                        tmp += current->toString(writeType);
                        tmp += _("\r\n");
                    }
                    tmp += _("]");
                    break;
                case AMF0DataType::AMF3Data:
                    tmp = _("AMF3 (");
                    tmp += ((AMFObject*)_content)->toString(writeType) + _(")");
                    break;
                default:
                        return _("Unknow Type");
            }
        }
        return tmp;
}
